#pragma once

#include "Singleton.h"
#include "Session/GateServerSession.h"

class TransMgr : public Singleton<TransMgr>
{
public:
	TransMgr();
	virtual ~TransMgr();

	void RunGC();

	struct Client {
		uint32 uid;
		uint32 gsGateSN;
		uint32 gateClientSN;
	};

	void AddClient(Client* pClient);
	void RemoveClient(uint32 uid);
	const Client* GetClient(uint32 uid);

	void AddGateServer(GateServerSession* pSession);
	void RemoveGateServer(GateServerSession* pSession);
	GateServerSession* GetGateServer(uint32 gsGateSN);

	void RemoveAllClient();
	void UpdateGateServerGSSN(uint32 oldGsGateSN, GateServerSession* pSession);

	void SendError2ClientSafe(uint32 uid, GErrorCode error);

	void SendPacket2ClientSafe(uint32 uid, const INetPacket& data);
	void BroadcastPacket2AllClientSafe(const INetPacket& data);

	void BroadcastPacket2AllGateServerSafe(const INetPacket& pck);
	void BroadcastPacket2AllGateServerSafe(const INetPacket& pck, const INetPacket& data);

private:
	std::shared_mutex m_clientMutex;
	std::unordered_map<uint32, Client*> m_clientMap;

	std::shared_mutex m_gateServerMutex;
	std::unordered_map<uint32, GateServerSession*> m_gateServerMap;

	std::queue<std::pair<std::unique_ptr<Client>, time_t>> m_recycleBin4Client;
	std::queue<std::pair<std::shared_ptr<Connection>, time_t>> m_recycleBin;
};

#define sTransMgr (*TransMgr::instance())
